package vn.sunnet.game.SinhTon.scroll;

import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;

public class ScrollLayer extends Group {

	private onMoveListener listener;

	// Khai bao 1 interface xu ly di chuyen
	public interface onMoveListener {
		public void StartMove();

		// CurrentPage: Trang hien tai, PageCount: so trang hay so anh trong
		// slide
		public void EndMove(int CurrentPage, int PageCount);
	}

	private boolean idle = true; // Trang thai de khong(ko lam viec gi)
	private boolean isPress = false;

	private float screenWidth;
	private float screenHeight;
	// Chieu dai va chieu cao cua scrollLayer
	private float sectionWidth, sectionHeight;
	private Group group;
	// Do dai dich chuyen
	private float amountX = 0;

	private int transmission; // huong dich chuyen
	// Neu luot sang ben phai duoc n trang thi
	// stopSection = n * sectionWidth
	private float stopSection = 0;
	private float speed = 1500; // Toc do chay
	private int currentSection = 1; // Trang hay anh hien tai
	private float flingSpeed = 1000; // Toc do quet

	private float overscrollDistance = 500; // khoang cach ma ta keo anh sang
											// ben phai hoac trai 500px

	private Rectangle cullingArea = new Rectangle();
	private Actor touchFocusedChild;
	private ActorGestureListener actorGestureListener;

	// PageWidth la khoang cach giua cac anh
	public ScrollLayer(Group group, float ScreenWidth, float ScreenHeight,
			float PageWidth) {
		this.addActor(group);
		init(ScreenWidth, ScreenHeight, PageWidth);
	}

	private void init(float ScreenWidth, float ScreenHeight, float PageWidth) {

		this.screenWidth = ScreenWidth;
		this.screenHeight = ScreenHeight;

		group = new Group();
		group.setZIndex(1);
		this.addActor(group);

		// Chieu dai va chieu cao cua scrollLayer
		sectionWidth = PageWidth / 3 + 70;
		sectionHeight = ScreenHeight;

		actorGestureListener = new ActorGestureListener() {

			@Override
			public void tap(InputEvent event, float x, float y, int count,
					int button) {

			}

			@Override
			public void pan(InputEvent event, float x, float y, float deltaX,
					float deltaY) {
				if (amountX < -overscrollDistance)
					return;
				if (amountX > (group.getChildren().size - 1) * sectionWidth
						+ overscrollDistance)
					return;

				amountX -= deltaX;

				cancelTouchFocusedChild();
			}

			@Override
			public void fling(InputEvent event, float velocityX,
					float velocityY, int button) {

				if (Math.abs(velocityX) > flingSpeed) {

					if (velocityX > 0)
						setStopSection(currentSection - 2);
					else
						setStopSection(currentSection);

				}

				cancelTouchFocusedChild();
			}

			@Override
			public void touchDown(InputEvent event, float x, float y,
					int pointer, int button) {

				isPress = true;
				idle = false;
				if (listener != null)
					listener.StartMove();

				// Cái này để kiểm tra và bỏ qua qua cái "Listener" khi chạm vào
				// một "button" nếu sau đó có trượt.
				// Mình dùng TextButton thì nó ra kiểu Label... Nếu bạn dùng một
				// actor nào đó có "Listener" khi chạm và muốn bỏ qua nó khi
				// trượt thì "debug" xem nó là kiểu class nào thì thay vào nhen
//				if (event.getTarget() instanceof Actor) {
//					touchFocusedChild = event.getTarget();
//				}

			}

			@Override
			public void touchUp(InputEvent event, float x, float y,
					int pointer, int button) {

				isPress = false;
				super.touchUp(event, x, y, pointer, button);
			}

		};

		this.addListener(actorGestureListener);

	}

	public void setListener(onMoveListener l) {
		this.listener = l;
	}

	public void addWidget(Actor widget) {
		widget.setX(this.group.getChildren().size * sectionWidth);
		widget.setY(0);
		widget.setWidth(sectionWidth);
		widget.setHeight(sectionHeight);

		group.addActor(widget);

	}

	// Tinh toan lai trang hien tai
	private int calculateCurrentSection() {
		int section = Math.round(amountX / sectionWidth) + 1;
		if (section > group.getChildren().size)
			return group.getChildren().size;
		if (section < 1)
			return 1;
		return section;
	}

	// Tra ve so trang trong slide
	private int getSectionsCount() {
		return group.getChildren().size;
	}

	private void setStopSection(int stoplineSection) {
		// stoplineSection la so trang ma da luot qua tinh tu trang dau tien
		// Khi luot sang phai thi giam, sang trai thi tang len
		if (stoplineSection < 0)
			stoplineSection = 0;
		if (stoplineSection > this.getSectionsCount() - 1)
			stoplineSection = this.getSectionsCount() - 1;

		stopSection = stoplineSection * sectionWidth;

		if (amountX < stopSection) {
			transmission = 1;
		} else {
			transmission = -1;
		}
	}

	public int currentPage() {
		return Math.round(amountX / sectionWidth);
	}

	public int pageCount() {
		return getSectionsCount();
	}

	private void move(float delta) {

		if (!isPress && amountX == stopSection) {
			if (!idle) {
				idle = true;
				if (listener != null)
					listener.EndMove(currentPage(), pageCount());
			}
		} else if (amountX < stopSection) {
			if (transmission == -1) {
				amountX = stopSection;
				currentSection = calculateCurrentSection();
				return;
			}
			amountX += speed * delta;

		} else if (amountX > stopSection) {
			if (transmission == 1) {
				amountX = stopSection;
				currentSection = calculateCurrentSection();
				return;
			}
			amountX -= speed * delta;
		}
	}

	@Override
	public void act(float delta) {

		super.act(delta);
		// Set vi tri cua group khi ma truot
		// group.setX co the tuy chinh (screenWidth / 2 - sectionWidth / 2) bang 
		// kich thuoc khac.nhung -amountX bat buoc phai co
		group.setX(-amountX + (screenWidth / 2 - sectionWidth / 2));

		cullingArea.set(group.getX() > 0 ? group.getX() : -group.getX(),
				group.getY(), screenWidth, screenHeight);
		group.setCullingArea(cullingArea); // set hay ko cung duoc

		// Neu ma pan thi tinh toan theo ham pan
		// Con ko thi tinh toan theo ham move(delta)
		if (actorGestureListener.getGestureDetector().isPanning()) {
			setStopSection(calculateCurrentSection() - 1);
		} else {
			move(delta);
		}
	}

	private void cancelTouchFocusedChild() {

		if (touchFocusedChild == null)
			return;
		try {

			touchFocusedChild.setScale(1);
			this.getStage().cancelTouchFocus(this.actorGestureListener, this);
		} catch (Exception e) {

		}

		touchFocusedChild = null;
	}

	public void setFlingSpeed(float _flingSpeed) {
		flingSpeed = _flingSpeed;
	}

	public void setSpeed(float _speed) {
		speed = _speed;
	}

	public void setOverscrollDistance(float _overscrollDistance) {
		overscrollDistance = _overscrollDistance;
	}

	// Truot tu dong sang muc ke tiep
	public void MoveToNextPage() {
		if (stopSection >= (getSectionsCount() - 1) * sectionWidth)
			return;

		idle = false;
		if (listener != null)
			listener.StartMove();

		stopSection += sectionWidth;
		transmission = 1;
	}

	// Truot tu dong ve muc truoc
	public void MoveToPreviousPage() {
		if (stopSection <= 0)
			return;

		idle = false;
		if (listener != null)
			listener.StartMove();

		stopSection -= sectionWidth;
		transmission = -1;
	}

	// Truot tu dong den trang bat ky
	public void MoveToPage(int page) {
		if (page < 0 || page >= getSectionsCount())
			return;

		idle = false;
		if (listener != null)
			listener.StartMove();

		float tmp = stopSection;
		stopSection = page * sectionWidth;
		if (stopSection > tmp)
			transmission = 1;
		else
			transmission = -1;
	}

	// Khong truot ma nhay ngay den trang bat ky
	public void SelectPage(int page) {
		if (page < 0 || page >= getSectionsCount())
			return;
		stopSection = page * sectionWidth;
		amountX = stopSection;

		idle = true;
		if (listener != null)
			listener.EndMove(currentPage(), pageCount());

	}

	public int getCurrentSection() {
		return currentSection;
	}

	public Group getGroup() {
		return group;
	}
}
